﻿#include "JsonData.h"

std::shared_ptr<GlobalData> GlobalData::GlobalInstance = nullptr;

JsonVideoClip::JsonVideoClip(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
        bool GlobalInited = false;
        for(const Json::Value VideoInfo : JsonInfo)
        {
            std::string VideoPath = JsonSetting::GetJsonString(&VideoInfo, "video_path");
            if(!VideoPath.empty())
            {
                VideoClipInfo* VideoInfoPtr = new VideoClipInfo();
                FFmpegReader* VideoReader = new FFmpegReader(VideoPath);
                
                VideoInfoPtr->Name = JsonSetting::GetJsonString(&VideoInfo, "name");
                VideoInfoPtr->File = VideoPath;
                VideoInfoPtr->Layer = JsonSetting::GetJsonInt(&VideoInfo, "layer");
                VideoInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&VideoInfo, "time", "timeline_start_function");
                VideoInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&VideoInfo, "time", "timeline_finish_function");
                VideoInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&VideoInfo, "time", "timeline_zoom_function");
                VideoInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&VideoInfo, "time", "position_time");
                VideoInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&VideoInfo, "time", "origin_begin_time");
                VideoInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&VideoInfo, "time", "origin_end_time");
                VideoInfoPtr->Width = VideoReader->info.width;
                VideoInfoPtr->Height = VideoReader->info.height;
                VideoInfoPtr->Fps = VideoReader->info.fps.ToFloat();
                VideoInfoPtr->VideoFrame = VideoReader->info.video_length;
                VideoInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&VideoInfo, "time", "zoom_rate");
                VideoInfoPtr->Hasvideo = JsonSetting::GetJsonBool(&VideoInfo, "has_video");
                VideoInfoPtr->HasAudio = JsonSetting::GetJsonBool(&VideoInfo, "has_audio");

                if(!GlobalInited)
                {
                    GlobalInited = true;
                    
                    Global->SetFps(VideoInfoPtr->Fps);
                    Global->SetVideoWidth(VideoInfoPtr->Width);
                    Global->SetVideoHeight(VideoInfoPtr->Height);
                    Global->SetVideoBitRate(VideoReader->info.video_bit_rate * 10);
                    Global->SetAudioSampleRate(VideoReader->info.sample_rate);
                    Global->SetAudioChannels(VideoReader->info.channels);
                    Global->SetAudioChannelLayout(VideoReader->info.channel_layout);
                    Global->SetAudioBitRate(VideoReader->info.audio_bit_rate);
                }
                
                JsonVideoClipArray.push_back(VideoInfoPtr);
                delete VideoReader;
                VideoReader = nullptr;
            }
        }
    }
}

JsonVideoClip::~JsonVideoClip()
{
    for(auto JsonVideoItem : JsonVideoClipArray)
    {
        delete JsonVideoItem;
        JsonVideoItem = nullptr;
    }
    JsonVideoClipArray.clear();
}

JsonAudioClip::JsonAudioClip(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
        bool GlobalInited = false;
        for(const Json::Value AudioInfo : JsonInfo)
        {
            std::string AudioPath = JsonSetting::GetJsonString(&AudioInfo, "audio_path");
            if(!AudioPath.empty())
            {
                AudioClipInfo* AudioInfoPtr = new AudioClipInfo();
                FFmpegReader* AudioReader = new FFmpegReader(AudioPath);
                
                AudioInfoPtr->Name = JsonSetting::GetJsonString(&AudioInfo, "name");
                AudioInfoPtr->File = AudioPath;
                AudioInfoPtr->Layer = JsonSetting::GetJsonInt(&AudioInfo, "layer");
                AudioInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&AudioInfo, "time", "timeline_start_function");
                AudioInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&AudioInfo, "time", "timeline_finish_function");
                AudioInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&AudioInfo, "time", "timeline_zoom_function");
                AudioInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&AudioInfo, "time", "position_time");
                AudioInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&AudioInfo, "time", "origin_begin_time");
                AudioInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&AudioInfo, "time", "origin_end_time");
                AudioInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&AudioInfo, "time", "zoom_rate");
                AudioInfoPtr->AudioFrame = AudioReader->info.video_length;
                AudioInfoPtr->HasAudio = JsonSetting::GetJsonBool(&AudioInfo, "has_audio");
                
                if(!GlobalInited)
                {
                    GlobalInited = true;
                    Global->SetAudioBitRate(AudioReader->info.audio_bit_rate);
                }
                
                JsonAudioClipArray.push_back(AudioInfoPtr);
            }
            else
            {
                cout << "cycserror:" << "cant find audio file:" << AudioPath << ";" << endl;
            }
        }
    }
}

JsonAudioClip::~JsonAudioClip()
{
    for(auto JsonAudioItem : JsonAudioClipArray)
    {
        delete JsonAudioItem;
        JsonAudioItem = nullptr;
    }
    JsonAudioClipArray.clear();
}

JsonVideoEffectClip::JsonVideoEffectClip(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        for(const Json::Value VideoEffectInfo : JsonInfo)
        {
            std::string VideoEffectPath = JsonSetting::GetJsonString(&VideoEffectInfo, "video_effect_path");
            if(!VideoEffectPath.empty())
            {
                VideoEffectClipInfo* VideoEffectInfoPtr = new VideoEffectClipInfo();
                FFmpegReader* VideoReader = new FFmpegReader(VideoEffectPath);
                
                VideoEffectInfoPtr->Name = JsonSetting::GetJsonString(&VideoEffectInfo, "name");
                VideoEffectInfoPtr->File = VideoEffectPath;
                VideoEffectInfoPtr->Layer = JsonSetting::GetJsonInt(&VideoEffectInfo, "layer");
                VideoEffectInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&VideoEffectInfo, "time", "timeline_start_function");
                VideoEffectInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&VideoEffectInfo, "time", "timeline_finish_function");
                VideoEffectInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&VideoEffectInfo, "time", "timeline_zoom_function");
                VideoEffectInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "time", "position_time");
                VideoEffectInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "time", "origin_begin_time");
                VideoEffectInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "time", "origin_end_time");
                VideoEffectInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "time", "zoom_rate");
                VideoEffectInfoPtr->VideoFrame = VideoReader->info.video_length;
                VideoEffectInfoPtr->Width = VideoReader->info.width;
                VideoEffectInfoPtr->Height = VideoReader->info.height;
                VideoEffectInfoPtr->Fps = VideoReader->info.fps.ToFloat();
                VideoEffectInfoPtr->IsRepeat = JsonSetting::GetJsonBool(&VideoEffectInfo, "repeat");
                VideoEffectInfoPtr->Hasvideo = JsonSetting::GetJsonBool(&VideoEffectInfo, "has_video");
                VideoEffectInfoPtr->HasAudio = JsonSetting::GetJsonBool(&VideoEffectInfo, "has_audio");
                VideoEffectInfoPtr->CoordX = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "x");
                VideoEffectInfoPtr->CoordY = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "y");
                VideoEffectInfoPtr->ScaleX = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "scale_x");
                VideoEffectInfoPtr->ScaleY = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "scale_y");
                VideoEffectInfoPtr->Rotation = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "rotation");
                VideoEffectInfoPtr->Alpha = JsonSetting::GetJsonObjectFloat(&VideoEffectInfo, "position", "alpha");

                JsonVideoEffectClipArray.push_back(VideoEffectInfoPtr);
                delete VideoReader;
                VideoReader = nullptr;
            }
            else
            {
                cout << "cycserror:" << "cant find video_effect file:" << VideoEffectPath << ";" << endl;
            }
        }
    }
}

JsonVideoEffectClip::~JsonVideoEffectClip()
{
    for(auto JsonVideoEffectItem : JsonVideoEffectClipArray)
    {
        delete JsonVideoEffectItem;
        JsonVideoEffectItem = nullptr;
    }
    JsonVideoEffectClipArray.clear();
}

JsonMaskEffect::JsonMaskEffect(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        for(const Json::Value EffectInfoItem : JsonInfo)
        {
            std::string EffectType = JsonSetting::GetJsonString(&EffectInfoItem, "type");
            if(MaskEffectFile.count(EffectType))
            {
                if(!EffectType.empty())
                {
                    MaskEffectInfo* MaskEffectInfoPtr = new MaskEffectInfo();

                    MaskEffectInfoPtr->Type = EffectType;
                    MaskEffectInfoPtr->Name = JsonSetting::GetJsonString(&EffectInfoItem, "name");
                    MaskEffectInfoPtr->File = MaskEffectFile[EffectType];
                    MaskEffectInfoPtr->TransitionIn = JsonSetting::GetJsonBool(&EffectInfoItem, "transition_in");
                    MaskEffectInfoPtr->Layer = JsonSetting::GetJsonInt(&EffectInfoItem, "layer");
                    MaskEffectInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_start_function");
                    MaskEffectInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_finish_function");
                    MaskEffectInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_zoom_function");
                    MaskEffectInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "position_time");
                    MaskEffectInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_begin_time");
                    MaskEffectInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_end_time");
                    MaskEffectInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "zoom_rate");

                    JsonMaskEffectArray.push_back(MaskEffectInfoPtr);
                }
                else
                {
                    cout << "cycserror:" << "cant find mask file:" << MaskEffectFile[EffectType] << ";" << endl;
                }
            }
        }
    }
}

JsonMaskEffect::~JsonMaskEffect()
{
    for(auto JsonMaskEffectItem : JsonMaskEffectArray)
    {
        delete JsonMaskEffectItem;
        JsonMaskEffectItem = nullptr;
    }
    JsonMaskEffectArray.clear();
}

JsonImageEffect::JsonImageEffect(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        for(const Json::Value EffectInfoItem : JsonInfo)
        {
            std::string EffectType = JsonSetting::GetJsonString(&EffectInfoItem, "type");
            if(EffectType == "image")
            {
                std::string File = JsonSetting::GetJsonString(&EffectInfoItem, "image_path");
                if(!File.empty())
                {
                    ImageEffectInfo* ImageEffectInfoPtr = new ImageEffectInfo();
                    FFmpegReader* VideoReader = new FFmpegReader(File);

                    ImageEffectInfoPtr->Type = EffectType;
                    ImageEffectInfoPtr->Name = JsonSetting::GetJsonString(&EffectInfoItem, "name");
                    ImageEffectInfoPtr->File = File;
                    ImageEffectInfoPtr->Layer = JsonSetting::GetJsonInt(&EffectInfoItem, "layer");
                    ImageEffectInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_start_function");
                    ImageEffectInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_finish_function");
                    ImageEffectInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_zoom_function");
                    ImageEffectInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "position_time");
                    ImageEffectInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_begin_time");
                    ImageEffectInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_end_time");
                    ImageEffectInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "zoom_rate");
                    ImageEffectInfoPtr->VideoFrame = VideoReader->info.video_length;
                    ImageEffectInfoPtr->CoordX = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "x");
                    ImageEffectInfoPtr->CoordY = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "y");
                    ImageEffectInfoPtr->ScaleX = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "scale_x");
                    ImageEffectInfoPtr->ScaleY = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "scale_y");
                    ImageEffectInfoPtr->Rotation = JsonSetting::GetJsonObjectInt(&EffectInfoItem, "position", "rotation");
                    ImageEffectInfoPtr->Alpha = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "alpha");
                    
                    JsonImageEffectArray.push_back(ImageEffectInfoPtr);
                }
                else
                {
                    cout << "cycserror:" << "cant find image file:" << File << ";" << endl;
                }
            }
        }
    }
}

JsonImageEffect::~JsonImageEffect()
{
    for(auto JsonImageEffectItem : JsonImageEffectArray)
    {
        delete JsonImageEffectItem;
        JsonImageEffectItem = nullptr;
    }
    JsonImageEffectArray.clear();
}

JsonFontEffect::JsonFontEffect(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        for(const Json::Value EffectInfoItem : JsonInfo)
        {
            std::string EffectType = JsonSetting::GetJsonString(&EffectInfoItem, "type");
            if(EffectType == "font")
            {
                string Text = JsonSetting::GetJsonString(&EffectInfoItem, "text");
                if(!Text.empty())
                {
                    FontEffectInfo* FontEffectInfoPtr = new FontEffectInfo();

                    FontEffectInfoPtr->Type = EffectType;
                    FontEffectInfoPtr->Name = JsonSetting::GetJsonString(&EffectInfoItem, "name");
                    FontEffectInfoPtr->Text = Text;
                    FontEffectInfoPtr->FontSize = JsonSetting::GetJsonInt(&EffectInfoItem, "font_size");
                    FontEffectInfoPtr->FontFile = JsonSetting::GetJsonString(&EffectInfoItem, "font_file");
                    FontEffectInfoPtr->FontType = JsonSetting::GetJsonString(&EffectInfoItem, "font_type");
                    FontEffectInfoPtr->Color = JsonSetting::GetJsonString(&EffectInfoItem, "color");
                    FontEffectInfoPtr->StrokeColor = JsonSetting::GetJsonString(&EffectInfoItem, "stroke_color");
                    FontEffectInfoPtr->StrokeWidth = JsonSetting::GetJsonFloat(&EffectInfoItem, "stroke_width");
                    FontEffectInfoPtr->Layer = JsonSetting::GetJsonInt(&EffectInfoItem, "layer");
                    FontEffectInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_start_function");
                    FontEffectInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_finish_function");
                    FontEffectInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&EffectInfoItem, "time", "timeline_zoom_function");
                    FontEffectInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "position_time");
                    FontEffectInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_begin_time");
                    FontEffectInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "origin_end_time");
                    FontEffectInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "time", "zoom_rate");
                    FontEffectInfoPtr->CoordX = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "x");
                    FontEffectInfoPtr->CoordY = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "y");
                    FontEffectInfoPtr->Alpha = JsonSetting::GetJsonObjectFloat(&EffectInfoItem, "position", "alpha");
                    
                    JsonFontEffectArray.push_back(FontEffectInfoPtr);
                }
                else
                {
                    cout << "cycserror:" << "fonteffect text is NULL" << ";" << endl;
                }
            }
        }
    }
}

JsonFontEffect::~JsonFontEffect()
{
    for(auto JsonFontEffectItem : JsonFontEffectArray)
    {
        delete JsonFontEffectItem;
        JsonFontEffectItem = nullptr;
    }
    JsonFontEffectArray.clear();
}

JsonShotCutCaption::JsonShotCutCaption(const Json::Value& JsonInfo)
{
    if(JsonInfo.isArray())
    {
        for(const Json::Value CaptionInfoItem : JsonInfo)
        {
            string Text = JsonSetting::GetJsonString(&CaptionInfoItem, "text");
            if(!Text.empty())
            {
                CaptionInfo* CaptionInfoPtr = new CaptionInfo();

                CaptionInfoPtr->Name = JsonSetting::GetJsonString(&CaptionInfoItem, "name");
                CaptionInfoPtr->Text = Text;
                CaptionInfoPtr->FontSize = JsonSetting::GetJsonInt(&CaptionInfoItem, "font_size");
                CaptionInfoPtr->FontFile = JsonSetting::GetJsonString(&CaptionInfoItem, "font_file");
                CaptionInfoPtr->FontType = JsonSetting::GetJsonString(&CaptionInfoItem, "font_type");
                CaptionInfoPtr->Rate = JsonSetting::GetJsonFloat(&CaptionInfoItem, "rate");
                CaptionInfoPtr->Color = JsonSetting::GetJsonString(&CaptionInfoItem, "color");
                CaptionInfoPtr->StrokeColor = JsonSetting::GetJsonString(&CaptionInfoItem, "stroke_color");
                CaptionInfoPtr->StrokeWidth = JsonSetting::GetJsonFloat(&CaptionInfoItem, "stroke_width");
                CaptionInfoPtr->Layer = JsonSetting::GetJsonInt(&CaptionInfoItem, "layer");
                CaptionInfoPtr->StartTimeFunc = JsonSetting::GetJsonObjectString(&CaptionInfoItem, "time", "timeline_start_function");
                CaptionInfoPtr->FinishTimeFunc = JsonSetting::GetJsonObjectString(&CaptionInfoItem, "time", "timeline_finish_function");
                CaptionInfoPtr->ZoomRateFunc = JsonSetting::GetJsonObjectString(&CaptionInfoItem, "time", "timeline_zoom_function");
                CaptionInfoPtr->PositionTime = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "time", "position_time");
                CaptionInfoPtr->BeginTime = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "time", "origin_begin_time");
                CaptionInfoPtr->EndTime = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "time", "origin_end_time");
                CaptionInfoPtr->ZoomRate = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "time", "zoom_rate");
                CaptionInfoPtr->CoordX = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "position", "x");
                CaptionInfoPtr->CoordY = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "position", "y");
                CaptionInfoPtr->Alpha = JsonSetting::GetJsonObjectFloat(&CaptionInfoItem, "position", "alpha");
                
                JsonCaptionInfoArray.push_back(CaptionInfoPtr);
            }
            else
            {
                cout << "cycserror:" << "caption text is NULL" << ";" << endl;
            }
        }
    }
}

JsonShotCutCaption::~JsonShotCutCaption()
{
    for(auto JsonCaptionEffectItem : JsonCaptionInfoArray)
    {
        delete JsonCaptionEffectItem;
        JsonCaptionEffectItem = nullptr;
    }
    JsonCaptionInfoArray.clear();
}